﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;

public class Goods : MonoBehaviour
{
    // 物品是否可被获取
    private bool CanBeGet = true;
    // 2D刚体组件
    private Rigidbody2D rb;
    // 动画控制器
    private Animator anim;
    // 2D碰撞体组件
    private Collider2D col;

    // 初始向下冲刺的时间（秒）
    [SerializeField] private float initialDownwardSprintTime = 1f;
    // 初始向下冲刺的力度
    [SerializeField] private float initialDownwardSprintForce = 3f;
    // 随机冲刺的间隔时间（秒）
    [SerializeField] private float sprintInterval = 2f;
    // 随机冲刺的力度
    [SerializeField] private float sprintForce = 2f;
    // 随机冲刺的距离
    [SerializeField] private float sprintDistance = 2f;
    // 减速度
    [SerializeField] private float deceleration = 5f;
    // 前方障碍物检测射线的距离
    [SerializeField] private float raycastDistance = 1f;
    // 玩家检测范围的半径
    [SerializeField] private float playerDetectionRadius = 3f;
    // 障碍物图层掩码
    [SerializeField] private LayerMask obstacleLayer;
    // 玩家图层掩码
    [SerializeField] private LayerMask playerLayer;
    // 障碍物图层名称（用于初始化图层掩码）
    [SerializeField] private string sandLayerName = "sand";
    // 玩家图层名称（用于初始化图层掩码）
    [SerializeField] private string playerLayerName = "Player";

    // 是否处于初始向下冲刺状态
    private bool isInitialDownwardSprint = true;
    // 初始向下冲刺的开始时间
    private float initialDownwardSprintStartTime;

    public SardineSpawner sardine;

    AudioSource audioSource;

    void Start()
    {
        GameObject Osaedine = GameObject.Find("沙丁鱼生成器");
        sardine = Osaedine.GetComponent<SardineSpawner>();

        audioSource = GetComponent<AudioSource>();
        audioSource.volume = PlayerPrefs.GetFloat("Volume", 1f);

        // 初始化图层掩码：将字符串名称转换为对应的图层索引
        obstacleLayer = 1 << LayerMask.NameToLayer(sandLayerName);
        playerLayer = 1 << LayerMask.NameToLayer(playerLayerName);

        // 获取组件引用
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        col = GetComponent<Collider2D>();

        // 记录初始冲刺的开始时间
        initialDownwardSprintStartTime = Time.time;
        // 施加初始向下的冲力
        Vector2 downwardDirection = Vector2.down;
        rb.AddForce(downwardDirection * initialDownwardSprintForce, ForceMode2D.Impulse);
        // 延迟调用随机移动方法
        Invoke("StartRandomMovement", initialDownwardSprintTime);
    }

    void Update()
    {
        // 更新动画状态
        anim.SetBool("CanBeGet", CanBeGet);
        // 初始向下冲刺结束后，重置速度
        if (isInitialDownwardSprint && Time.time - initialDownwardSprintStartTime >= initialDownwardSprintTime)
        {
            rb.velocity = Vector2.zero;
            isInitialDownwardSprint = false;
        }
    }

    // 开始随机移动的协程
    private void StartRandomMovement()
    {
        StartCoroutine(SprintCoroutine());
    }

    // 物品移动的主协程逻辑
    private IEnumerator SprintCoroutine()
    {
        while (CanBeGet) // 物品可被获取时循环
        {
            Vector2 sprintDirection; // 移动方向

            // 检测周围是否有玩家
            Collider2D playerCollider = DetectNearbyPlayer();

            if (playerCollider != null)
            {
                // 检测到玩家时，计算逃离方向
                sprintDirection = GetEscapeDirection(playerCollider.transform.position);
                Debug.Log("检测到玩家，向反方向逃跑");
            }
            else
            {
                // 未检测到玩家时，获取随机有效方向
                sprintDirection = GetValidDirection();
            }

            // 根据水平方向翻转图像
            if (sprintDirection.x < 0)
            {
                transform.localScale = new Vector2(-0.3f, 0.3f);
            }
            else
            {
                transform.localScale = new Vector2(0.3f, 0.3f);
            }

            // 施加冲刺力
            rb.AddForce(sprintDirection * sprintForce, ForceMode2D.Impulse);
            Vector2 startPosition = rb.position; // 记录起始位置
            bool isDecelerating = false; // 是否处于减速状态

            // 冲刺过程中持续检测（未达到冲刺距离且物品可被获取时）
            while (Vector2.Distance(rb.position, startPosition) < sprintDistance && CanBeGet)
            {
                // 检测前方是否有障碍物
                if (IsPathBlocked(sprintDirection))
                {
                    rb.velocity = Vector2.zero; // 清除当前速度

                    // 根据是否检测到玩家，选择不同的新方向策略
                    Vector2 newDirection;
                    if (playerCollider != null)
                    {
                        // 有玩家时，重新计算逃离方向
                        newDirection = GetEscapeDirection(playerCollider.transform.position);
                    }
                    else
                    {
                        // 无玩家时，获取随机有效方向
                        newDirection = GetValidDirection();
                    }

                    if (newDirection != Vector2.zero)
                    {
                        sprintDirection = newDirection; // 更新移动方向

                        // 重新翻转图像
                        if (sprintDirection.x < 0)
                        {
                            transform.localScale = new Vector2(-0.3f, 0.3f);
                        }
                        else
                        {
                            transform.localScale = new Vector2(0.3f, 0.3f);
                        }

                        rb.AddForce(sprintDirection * sprintForce, ForceMode2D.Impulse);
                        startPosition = rb.position; // 重置起始位置
                    }
                }

                // 持续检测玩家，确保方向远离玩家
                playerCollider = DetectNearbyPlayer();
                if (playerCollider != null && !IsDirectionTowardsPlayer(sprintDirection, playerCollider.transform.position))
                {
                    // 方向不远离玩家时，重新计算逃离方向
                    rb.velocity = Vector2.zero;
                    sprintDirection = GetEscapeDirection(playerCollider.transform.position);

                    // 重新翻转图像
                    if (sprintDirection.x < 0)
                    {
                        transform.localScale = new Vector2(-0.3f, 0.3f);
                    }
                    else
                    {
                        transform.localScale = new Vector2(0.3f, 0.3f);
                    }

                    rb.AddForce(sprintDirection * sprintForce, ForceMode2D.Impulse);
                    startPosition = rb.position; // 重置起始位置
                }

                yield return null; // 等待下一帧
            }

            // 冲刺结束后进入减速阶段
            isDecelerating = true;
            while (isDecelerating)
            {
                Vector2 velocity = rb.velocity;
                // 平滑减速至零
                velocity = Vector2.MoveTowards(velocity, Vector2.zero, deceleration * Time.deltaTime);
                rb.velocity = velocity;

                if (velocity.magnitude <= 0.01f)
                {
                    isDecelerating = false; // 速度足够小时，结束减速
                }
                yield return null;
            }

            // 等待下一次冲刺的间隔时间
            yield return new WaitForSeconds(sprintInterval);
        }
    }

    // 检测周围指定范围内的玩家
    private Collider2D DetectNearbyPlayer()
    {
        // 获取指定范围内所有玩家图层的碰撞体
        Collider2D[] hitColliders = Physics2D.OverlapCircleAll(transform.position, playerDetectionRadius, playerLayer);

        // 绘制检测范围的可视化射线（用于调试）
        Debug.DrawRay(transform.position, Vector2.up * playerDetectionRadius, Color.yellow, 0.1f);
        Debug.DrawRay(transform.position, Vector2.down * playerDetectionRadius, Color.yellow, 0.1f);
        Debug.DrawRay(transform.position, Vector2.left * playerDetectionRadius, Color.yellow, 0.1f);
        Debug.DrawRay(transform.position, Vector2.right * playerDetectionRadius, Color.yellow, 0.1f);

        // 遍历碰撞体，排除自身后返回第一个玩家碰撞体
        foreach (Collider2D collider in hitColliders)
        {
            if (collider.gameObject != gameObject)
            {
                return collider;
            }
        }

        return null; // 未检测到玩家
    }

    // 计算逃离玩家的方向（在反向半圆范围内）
    private Vector2 GetEscapeDirection(Vector3 playerPosition)
    {
        // 计算从玩家到物品的单位方向向量
        Vector2 directionToItem = (transform.position - playerPosition).normalized;

        // 将向量转换为角度（度）
        float angle = Mathf.Atan2(directionToItem.y, directionToItem.x) * Mathf.Rad2Deg;

        // 在反向半圆（180度范围）内生成随机角度
        float randomAngleInSemicircle = angle + Random.Range(-90f, 90f);

        // 将角度转换为单位向量（极坐标转笛卡尔坐标）
        Vector2 escapeDirection = new Vector2(
            Mathf.Cos(randomAngleInSemicircle * Mathf.Deg2Rad),
            Mathf.Sin(randomAngleInSemicircle * Mathf.Deg2Rad)
        );

        // 检查新方向是否被障碍物阻挡
        if (!IsPathBlocked(escapeDirection))
        {
            return escapeDirection; // 方向有效时直接返回
        }

        // 方向无效时，尝试多个调整后的角度
        for (int i = 0; i < 5; i++)
        {
            float adjustedAngle = randomAngleInSemicircle + Random.Range(-45f, 45f);
            Vector2 adjustedDirection = new Vector2(
                Mathf.Cos(adjustedAngle * Mathf.Deg2Rad),
                Mathf.Sin(adjustedAngle * Mathf.Deg2Rad)
            );

            if (!IsPathBlocked(adjustedDirection))
            {
                return adjustedDirection; // 找到有效方向后返回
            }
        }

        // 所有尝试失败时，返回原始反方向（可能被阻挡，但强制移动）
        return directionToItem;
    }

    // 检查当前移动方向是否朝向玩家
    private bool IsDirectionTowardsPlayer(Vector2 direction, Vector3 playerPosition)
    {
        // 计算从物品到玩家的单位方向向量
        Vector2 directionToPlayer = (playerPosition - transform.position).normalized;
        // 计算两个向量的点积（用于判断方向是否接近）
        float dotProduct = Vector2.Dot(direction, directionToPlayer);

        // 点积大于0表示方向大致朝向玩家
        return dotProduct > 0;
    }

    // 检测指定方向是否被障碍物阻挡
    private bool IsPathBlocked(Vector2 direction)
    {
        // 从碰撞体中心发射射线
        Vector2 rayOrigin = col.bounds.center;
        RaycastHit2D hit = Physics2D.Raycast(rayOrigin, direction, raycastDistance, obstacleLayer);

        // 绘制射线（用于调试）
        Debug.DrawRay(rayOrigin, direction * raycastDistance, Color.green, 0.1f);

        // 射线命中障碍物时返回true
        return hit.collider != null;
    }

    // 获取一个未被障碍物阻挡的随机有效方向
    private Vector2 GetValidDirection()
    {
        int maxAttempts = 4; // 最大尝试次数
        int attempts = 0;

        while (attempts < maxAttempts)
        {
            // 生成随机角度并转换为方向向量
            float randomAngle = Random.Range(0f, 360f);
            Vector2 direction = Quaternion.Euler(0, 0, randomAngle) * Vector2.right;

            if (!IsPathBlocked(direction))
            {
                return direction; // 方向有效时返回
            }

            attempts++;
        }

        // 尝试失败时返回任意随机方向（可能被阻挡）
        return Quaternion.Euler(0, 0, Random.Range(0f, 360f)) * Vector2.right;
    }

    // 当与玩家发生碰撞时的处理
    private void OnCollisionEnter2D(Collision2D collision)
    {
        PlayerController otherPlayer = collision.gameObject.GetComponent<PlayerController>();
        if (otherPlayer != null && CanBeGet)
        {
            CanBeGet = false; // 物品不可再被获取

            sardine.DecrementSardineCount();

            // 冻结物体的位置和旋转
            rb.constraints = RigidbodyConstraints2D.FreezePositionX |
                             RigidbodyConstraints2D.FreezeRotation |
                             RigidbodyConstraints2D.FreezePositionY;
            otherPlayer.Score++; // 增加玩家分数
        }
    }
    private void PlayAudio()
    {
        audioSource.Play();
        gameObject.GetComponent<BoxCollider2D>().enabled = false;
    }

    // 删除自身的方法
    private void DeleteSelf()
    {
        Destroy(gameObject);
    }
}